"""
搜索管理模块

版本日志：
v1.0 2024-03-xx
- 初始版本
- 实现全局搜索功能
- 实现分类内搜索功能
- 实现搜索结果高亮
v1.1 2024-03-xx
- 升级搜索算法，支持空格分隔的多关键词AND逻辑
v1.2 2024-03-xx
- 优化搜索性能，改用同步搜索
- 优化搜索算法，提高大量文档搜索速度
"""

import re
import json
from typing import List, Dict, Tuple, Set
from concurrent.futures import ThreadPoolExecutor
import threading

class SearchManager:
    def __init__(self, data_manager):
        self.data_manager = data_manager
        self._cache = {}  # 文件内容缓存
        self._cache_lock = threading.Lock()  # 缓存锁
        
    def global_search(self, keyword: str) -> List[Tuple[str, Dict]]:
        """全局搜索
        返回: [(文件名, 文件数据), ...]
        """
        if not keyword:
            return []
            
        # 预处理关键词
        keywords = self._preprocess_keywords(keyword)
        if not keywords:
            return []
            
        results = []
        files = self.data_manager.get_all_files()
        
        # 对每个文件执行搜索
        for file in files:
            result = self._search_file(file, keywords)
            if result:
                results.append(result)
                
        return results
        
    def group_search(self, keyword: str, group: str) -> List[Tuple[str, Dict]]:
        """分组内搜索
        返回: [(文件名, 文件数据), ...]
        """
        if not keyword or not group:
            return []
            
        # 预处理关键词
        keywords = self._preprocess_keywords(keyword)
        if not keywords:
            return []
            
        results = []
        files = self.data_manager.get_files_by_group(group)
        
        # 对每个文件执行搜索
        for file in files:
            result = self._search_file(file, keywords)
            if result:
                results.append(result)
                
        return results
        
    def _preprocess_keywords(self, keyword: str) -> Set[str]:
        """预处理关键词，返回小写关键词集合"""
        return {k.lower().strip() for k in keyword.split() if k.strip()}
        
    def _search_file(self, file: str, keywords: Set[str]) -> Tuple[str, Dict]:
        """在单个文件中搜索关键词
        
        Args:
            file: 文件名
            keywords: 预处理后的关键词集合
            
        Returns:
            Tuple[str, Dict] or None: 如果找到匹配则返回(文件名, 数据)，否则返回None
        """
        try:
            # 检查缓存
            with self._cache_lock:
                if file in self._cache:
                    data = self._cache[file]
                else:
                    with open(self.data_manager.get_data_path(file), 'r', encoding='utf-8') as f:
                        data = json.load(f)
                        self._cache[file] = data
                    
            # 快速检查每个字段
            for field in ['name', 'content', 'comment', 'group']:
                field_value = str(data.get(field, '')).lower()
                if all(kw in field_value for kw in keywords):
                    return (file, data)
                    
            return None
            
        except Exception as e:
            print(f"搜索文件出错: {file}, {str(e)}")
            return None
            
    def get_highlight_ranges(self, text: str, keyword: str) -> List[Tuple[int, int]]:
        """获取需要高亮的文本范围，支持多关键词
        返回: [(开始位置, 结束位置), ...]
        """
        if not text or not keyword:
            return []
            
        ranges = []
        text_lower = text.lower()
        
        # 使用预处理的关键词
        keywords = self._preprocess_keywords(keyword)
        
        # 为每个关键词查找匹配位置
        for kw in keywords:
            pattern = re.escape(kw)
            for match in re.finditer(pattern, text_lower):
                ranges.append((match.start(), match.end()))
                
        # 按位置排序
        ranges.sort()
        return ranges
        
    def clear_cache(self):
        """清除文件内容缓存"""
        with self._cache_lock:
            self._cache.clear()